package com.example.demo.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;


@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsService userDetailsService;


    @Override
    /**
     * 定制用户认证管理器
     *
     * 用途：定义用户及密码 以及对定义好的用户进行角色授权
     */
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //userDetailService验证方式
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        auth
                //userDetailsService() 采用:userDetailService验证方式 里面传入
                .userDetailsService(userDetailsService)
                //passwordEncoder() ：密码编辑的方法  里面传入的参数是真正密码加密的形式（采用什么进行对密码的加密）

                //真正的对密码进行判断是在这里执行(前面的查询只是根据用户名 并不涉及密码的判断)
                .passwordEncoder(encoder);
    }

    @Override
    /**
     * 定制基于HTTP请求的用户访问控制
     *
     * 用途：
     * 1.定义角色和资源的关系（对角色和资源进行对应的分配）
     * 2.规定请求的拦截方式（那些需要进行拦截 哪些则不需要）
     */
    protected void configure(HttpSecurity http) throws Exception {

        http
                //有了这个方法 才可以对请求进行配置
                .authorizeRequests()
                //访问该请求地址需要以下权限
                .antMatchers("/admin")
                .hasRole("admin")
//                .antMatchers("/client/**")
//                .access("hasRole('common') or hasRole('admin')")
                //对请求地址进行放行
                .antMatchers("/**", "/login", "/register", "/checkUsername", "/checkFirstPassword", "/checkSecondPassword", "/toRegister")
                .permitAll()
                //对static下面的文件进行放行
                .antMatchers("/article_img/**", "/assets/**", "/back/**", "/js/**", "/user/**")
                .permitAll()
                //对所有请求的配置
                .anyRequest()
                //都必须要验证
                .authenticated()
                .and()
                //对登录请求的配置
                .formLogin()
                //登录地址必须是/login 如果是其他的回报404的错误 并且不进入自己定义的userdetailservice类
                .loginPage("/login")
                .defaultSuccessUrl("/")
                .and()
                //对退出请求的配置
                .logout()
                //进了该请求地址后 security内部会清空授权信息
                .logoutUrl("/logout")
                .logoutSuccessUrl("/")
                .and()
                //将跨域请求进行关闭（默认是开启的） 原因：退出时会提示404的错误
                .csrf()
                .disable();

    }

}
